<?php



namespace App\Http\Controllers\Backend1;

use App\Services\Base\Interfaces\ConfigServiceInterface;
use App\Services\Business\Interfaces\CourseServiceInterface;
use App\Services\Business\Models\CourseTag;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Services\Member\Models\User;
use App\Events\CourseCreatedEvent;
use App\Events\CourseUpdatedEvent;
use App\Services\Business\Models\Video;
use App\Services\Business\Models\Course;
use App\Events\CourseDestroyedEvent;
use App\Services\Member\Models\UserCourse;
use App\Http\Requests\Backend\CourseRequest;
use App\Services\Business\Models\CourseChapter;
use App\Services\Business\Models\Category;
use App\Services\Business\Models\CourseUserRecord;
use App\Services\Member\Models\UserVideoWatchRecord;
use Illuminate\Support\Facades\Log;

class CourseController extends BaseController
{
    public function all(Request $request)
    {
        $corpId = $request->header("corpid", 0);
        $courses = Course::corpId($corpId)->select(['id', 'title'])->get();
        return $this->successData(['data' => $courses]);
    }

    public function index(Request $request)
    {
        $id       = $request->input('id');
        $keywords = $request->input('keywords', '');
        $cid      = $request->input('cid');
        $corpId   = $request->header("corpid", 0);
        // 排序
        $sort       = $request->input('sort', 'created_at');
        $order      = $request->input('order', 'desc');

        $courses = Course::query()
            ->select([
                'id', 'user_id', 'title', 'slug', 'thumb', 'charge', 'short_description',
                'is_show', 'category_id', 'is_recommend', 'user_count', 'is_free',
                'created_at', 'updated_at',
            ])
            ->with(['category:id,name'])
            ->withCount(['videos', 'chapters', 'comments'])
            ->when($id, function ($query) use ($id) {
                $query->where('id', $id);
            })
            ->when($keywords, function ($query) use ($keywords) {
                return $query->where('title', 'like', '%' . $keywords . '%');
            })
            ->when($cid, function ($query) use ($cid) {
                return $query->whereCategoryId($cid);
            })
            ->orderBy($sort, $order)
            ->paginate($request->input('size', 10));

        $categories = Category::query()->select(['id', 'name'])->orderBy('sort')->get();

        return $this->successData(compact('courses', 'categories'));
    }

    public function create(Request $request)
    {
        $corpId = $request->header("corpid", 0);
        $categories = Category::corpId($corpId)
            ->select(['id', 'name', 'sort', 'cate_id'])
            ->with(['children:id,parent_id,sort,name,cate_id'])
            ->where('parent_id', 0)
            ->orderBy('sort')
            ->get();
        return $this->successData(compact('categories'));
    }

    public function store(CourseRequest $request, Course $course)
    {
        $course->fill($request->filldata())->save();

        event(new CourseCreatedEvent(
            $course['id'],
            $course['title'],
            $course['charge'],
            $course['thumb'],
            $course['short_description'],
            $course['original_desc']
        ));
        $tags          = (array)$request->input('tags');
        $tagCategoryId = (int)$request->input('tag_category_id');
        if (!empty($tags)) {
            foreach ($tags as $tag) {
                CourseTag::create([
                    "course_id"       => $course->id,
                    "video_tags_id"   => $tag,
                    "tag_category_id" => $tagCategoryId
                ]);
            }
        }
        return $this->success();
    }

    public function edit($id)
    {
        $course    = Course::query()->where('id', $id)->firstOrFail();
        $videoTags = CourseTag::query()->where('course_id', $id)->get();
        $tags      = [];
        if (!empty($videoTags)) {
            foreach ($videoTags as $v) {
                $tags[] = $v['video_tags_id'];
            }
        }
        $course->tags     = $tags;
        $category         = Category::query()->where('id', $course->category_id)->first();
        $course->category = $category;
        return $this->successData($course);
    }

    public function update(CourseRequest $request, $id)
    {
        $data = $request->filldata();

        $course = Course::query()->where('id', $id)->firstOrFail();

        $course->fill($data)->save();

        event(new CourseUpdatedEvent(
            $course['id'],
            $course['title'],
            $course['charge'],
            $course['thumb'],
            $course['short_description'],
            $course['original_desc']
        ));
        CourseTag::query()->where('course_id', $id)->delete();
        $tags = (array)$request->input('tags');
        if (!empty($tags)) {
            foreach ($tags as $tag) {
                CourseTag::create([
                    "course_id"       => $course->id,
                    "video_tags_id"   => $tag,
                    "tag_category_id" => 0
                ]);
            }
        }

        return $this->success();
    }

    public function destroy($id)
    {
        $course = Course::query()->where('id', $id)->firstOrFail();

        if ($course->videos()->exists()) {
            return $this->error(__('当前课程下存在视频无法删除'));
        }

        $course->delete();

        event(new CourseDestroyedEvent($id));

        return $this->success();
    }





    // 订阅记录
    public function subscribes(Request $request, $courseId)
    {
        $userId           = $request->input('user_id');
        $subscribeStartAt = $request->input('subscribe_start_at');
        $subscribeEndAt   = $request->input('subscribe_end_at');

        $data = UserCourse::query()
            ->when($userId, function ($query) use ($userId) {
                $query->where('user_id', $userId);
            })
            ->when($subscribeStartAt && $subscribeEndAt, function ($query) use ($subscribeStartAt, $subscribeEndAt) {
                $query->whereBetween('created_at', [Carbon::parse($subscribeStartAt), Carbon::parse($subscribeEndAt)]);
            })
            ->where('course_id', $courseId)
            ->orderByDesc('created_at')
            ->paginate($request->input('size', 10));

        $users = User::query()
            ->select(['id', 'nick_name', 'mobile', 'avatar'])
            ->whereIn('id', array_column($data->items(), 'user_id'))
            ->get()
            ->keyBy('id');

        return $this->successData([
            'data'  => $data,
            'users' => $users,
        ]);
    }

    public function createSubscribe(Request $request, $courseId)
    {
        $userId = $request->input('user_id');
        if (!$userId) {
            return $this->error(__('参数错误'));
        }

        if (!is_array($userId)) {
            $userId = [$userId];
        }

        $existsIds = UserCourse::query()
            ->whereIn('user_id', $userId)
            ->where('course_id', $courseId)
            ->select(['user_id'])
            ->get()
            ->pluck('user_id')
            ->toArray();

        $userId = array_diff($userId, $existsIds);

        foreach ($userId as $id) {
            UserCourse::create([
                'course_id'  => $courseId,
                'user_id'    => $id,
                'charge'     => 0,
                'created_at' => Carbon::now(),
            ]);
        }

        // 课程订阅数量更新
        Course::query()
            ->where('id', $courseId)
            ->update([
                'user_count' => UserCourse::query()->where('course_id', $courseId)->count(),
            ]);

        return $this->success();
    }

    public function deleteSubscribe(Request $request, $courseId)
    {
        $userId = $request->input('user_id');

        UserCourse::query()->where('course_id', $courseId)->where('user_id', $userId)->delete();

        // 课程订阅数量更新
        Course::query()
            ->where('id', $courseId)
            ->decrement('user_count');

        return $this->success();
    }



    public function importUsers(Request $request, $id)
    {
        $mobileList = $request->input('mobiles');
        if (!$mobileList || !is_array($mobileList)) {
            return $this->error(__('参数错误'));
        }

        // 剔除空行
        $mobiles = [];
        foreach ($mobileList as $mobile) {
            $mobile && $mobiles[] = $mobile;
        }

        if (count($mobiles) > 1000) {
            return $this->error(__('一次最多导入:count名学员', ['count' => 1000]));
        }

        // 重复手机号检测
        $uniqueMobiles = array_flip(array_flip($mobiles));
        if (count($mobiles) !== count($uniqueMobiles)) {
            return $this->error(__('手机号重复'));
        }

        $registerMobiles = [];
        $mobile2id       = [];

        // 校验手机号是否为本站注册学员
        foreach (array_chunk($mobiles, 100) as $mobilesChunk) {
            $tmp             = User::query()->whereIn('mobile', $mobilesChunk)->select(['id', 'mobile'])->get();
            $registerMobiles = array_merge($registerMobiles, $tmp->pluck('mobile')->toArray());
            $mobile2id       = array_merge($mobile2id, $tmp->toArray());
        }
        $mobile2id = array_column($mobile2id, 'id', 'mobile');
        $diff      = array_diff($mobiles, $registerMobiles);
        if ($diff) {
            return $this->error(__('手机号[:mobiles]非本站注册学员', ['mobiles' => implode(',', $diff)]));
        }

        $userId2mobile = array_flip($mobile2id);
        $userIds       = array_values($mobile2id);

        // 校验是否有重复导入的学员手机号
        foreach (array_chunk($userIds, 200) as $userIdsChunk) {
            $existsUserIds = UserCourse::query()
                ->whereIn('user_id', $userIdsChunk)
                ->where('course_id', $id)
                ->select(['user_id'])
                ->get()
                ->pluck('user_id')
                ->toArray();
            if ($existsUserIds) {
                $tmpMobiles = array_map(function ($userId) use ($userId2mobile) {
                    return $userId2mobile[$userId];
                }, $existsUserIds);
                return $this->error(__('手机号[:mobiles]已关联课程，请勿重复导入', ['mobiles' => implode(',', $tmpMobiles)]));
            }
        }

        DB::transaction(function () use ($id, $userIds) {
            $now = date('Y-m-d H:i:s');
            foreach (array_chunk($userIds, 150) as $userIdsChunk) {
                $insertData = [];
                foreach ($userIdsChunk as $userId) {
                    $insertData[] = [
                        'course_id'  => $id,
                        'user_id'    => $userId,
                        'created_at' => $now,
                        'charge'     => 0,
                    ];
                }
                $insertData && UserCourse::insert($insertData);
            }
        });

        return $this->success();
    }


    public function destoryMulti(Request $request, ConfigServiceInterface $configService, CourseServiceInterface $courseService)
    {
        $ids = (array)$request->input("ids", []);
        if (empty($ids)) {
            return $this->success();
        }
        try {
            $courses = Course::query()->findMany($ids);
            $courseService->deleteVideos($courses, $configService);
        } catch (\Exception $exception) {
            Log::error($exception);
        }
        Course::destroy($ids);
        return $this->success();
    }
}
